/*
 * Copyright 2008-2023 dexian.vip. All rights reserved.
 * Support: http://www.dexian.vip
 * License: http://www.dexian.vip/license
 */

package vip.dexian.code.path.admin;

import vip.dexian.code.config.Path;
import vip.dexian.code.generator.Config;
import vip.dexian.code.template.enums.TemplateEnum;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.util.Assert;

import java.util.HashMap;
import java.util.Map;

/**
 * @author 挺好的 2023年06月06日 14:13
 */
public class AdminPathUtils {

    // =========== 生成不同模块的内容，修改以下内容 ============

    /**
     * 项目所在目录
     */
    public static final String PROJECT_DIRECTORY = Config.PROJECT_DIRECTORY;

    /**
     * controller 基础requestMapping。
     */
    private static final String BASE_REQUEST_MAPPING = "/admin/admin/";

    /**
     * 基础包名 【其他模块请修改】， 如： vip.dexian.product.
     */
    private static final String BASE_PACKAGE_NAME = "vip.dexian.admin.";

    /**
     * 基础路径
     */
    private static final String BASE_LOCATION = PROJECT_DIRECTORY + "/";

    /**
     * dao的基础路径
     */
    static final String DAO_LOCATION = BASE_LOCATION + "dexian-dao/src/main/java/";

    /**
     * dao实现基础路径
     */
    static final String DAO_IMPL_LOCATION = DAO_LOCATION;

    /**
     * 实体图基础路径
     */
    static final String GRAPH_LOCATION = DAO_LOCATION;

    /**
     * dto基础路径
     */
    static final String DTO_LOCATION = BASE_LOCATION + "dexian-bean/src/main/java/";

    /**
     * dto assembler 基础路径
     */
    static final String DTO_MAPPER_LOCATION = BASE_LOCATION + "dexian-manager/src/main/java/";

    /**
     * service 基础路径
     */
    static final String SERVICE_LOCATION = BASE_LOCATION + "dexian-service/src/main/java/";

    /**
     * service impl 基础路径
     */
    static final String SERVICE_IMPL_LOCATION = SERVICE_LOCATION;

    /**
     * command基础路径
     */
    static final String FORM_LOCATION = BASE_LOCATION + "dexian-bean/src/main/java/";

    /**
     * command assembler基础路径
     */
    static final String FORM_MAPPER_LOCATION = BASE_LOCATION + "dexian-manager/src/main/java/";

    /**
     * controller基础路径
     */
    static final String CONTROLLER_LOCATION = BASE_LOCATION + "dexian-admin/src/main/java/";

    /**
     * dao包名
     */
    static final String BASE_PACKAGE_DAO = BASE_PACKAGE_NAME + "dao";

    /**
     * daoImpl 包名
     */
    static final String BASE_PACKAGE_DAO_IMPL = BASE_PACKAGE_NAME + "dao.impl";

    /**
     * graph 包名
     */
    static final String BASE_PACKAGE_GRAPH = BASE_PACKAGE_NAME + "entity.graph";

    /**
     * dto 包名
     */
    static final String BASE_PACKAGE_DTO = BASE_PACKAGE_NAME + "dto";

    /**
     * daoMapper 包名
     */
    static final String BASE_PACKAGE_DTO_MAPPER = BASE_PACKAGE_NAME + "assembler";

    /**
     * service 包名
     */
    static final String BASE_PACKAGE_SERVICE = BASE_PACKAGE_NAME + "service";

    /**
     * daoImpl 包名
     */
    static final String BASE_PACKAGE_SERVICE_IMPL = BASE_PACKAGE_NAME + "service.impl";

    /**
     * form 包名
     */
    static final String BASE_PACKAGE_FORM = BASE_PACKAGE_NAME + "command";

    /**
     * form mapper 包名
     */
    static final String BASE_PACKAGE_FORM_MAPPER = BASE_PACKAGE_NAME + "assembler";

    /**
     * searcher
     */
    static final String BASE_PACKAGE_SEARCHER = BASE_PACKAGE_NAME + "searcher";

    /**
     * controller 包名
     */
    static final String BASE_PACKAGE_CONTROLLER = BASE_PACKAGE_NAME + "controller";

    /**
     * SQL语句存放的位置
     */
    static final String BASE_SQL = "vip.dexian.code.generate.sql";

    /**
     * SQL放置的地方
     */
    public static final String SQL_LOCATION = PROJECT_DIRECTORY + "/code-generator/src/main/java/";

    /**
     * 临时页面权限路径
     */
    public static final String PERMS_PAGE_LOCATION = BASE_LOCATION + "dexian-admin/src/main/resources/templates/admin/admin/role/perms/temp.ftl";

    /**
     * 权限配置yml文件路径
     */
    public static final String PERMS_YML_LOCATION = BASE_LOCATION + "dexian-admin/src/main/resources/application-authorize.yml";

    /**
     * 页面文件存放目录
     */
    public static final String PAGES_LOCATION = BASE_LOCATION + "dexian-admin/src/main/resources/templates/admin/";

    // =========== 生成不同模块的内容，修改以上内容 ============

    /**
     * 存放生成类的文件信息
     */
    private static final Map <String, Path> PATHS;

    static {

        PATHS = new HashMap <>();

        add(TemplateEnum.DAO);

        add(TemplateEnum.DAO_IMPL);

        add(TemplateEnum.GRAPH);

        add(TemplateEnum.DTO);

        add(TemplateEnum.DTO_MAPPER);

        add(TemplateEnum.SERVICE);

        add(TemplateEnum.SERVICE_IMPL);

        add(TemplateEnum.SAVE_FORM);

        add(TemplateEnum.UPDATE_FORM);

        add(TemplateEnum.PAGE_FORM);

        add(TemplateEnum.LIST_FORM);

        add(TemplateEnum.SAVE_MAPPER);

        add(TemplateEnum.UPDATE_MAPPER);

        add(TemplateEnum.CONTROLLER);

        add(TemplateEnum.SQL);

    }

    /**
     * 获取Path
     *
     * @param templateEnum
     *         模板
     *
     * @return
     */
    public static Path getPath (TemplateEnum templateEnum) {
        Assert.notNull(templateEnum, "模板不能为空");

        return PATHS.get(templateEnum.getName());
    }

    /**
     * 添加模板
     *
     * @param templateEnum
     *         模板
     */
    static void add (TemplateEnum templateEnum) {
        Assert.notNull(templateEnum, "模板不能为空");

        Pair <String, String> pair = getPathAndPackage(templateEnum);

        String baseFilePath = pair.getLeft();
        String packageName = pair.getRight();

        Path path = Path.builder().baseFilePath(baseFilePath).basePackage(packageName)
                .requestMappingPrefix(BASE_REQUEST_MAPPING).build();

        PATHS.put(templateEnum.getName(), path);
    }

    /**
     * 获取包名名称
     *
     * @param templateEnum
     *         模板
     *
     * @return
     */
    private static String getPackageName (TemplateEnum templateEnum) {

        switch (templateEnum) {
            case DAO:
                return BASE_PACKAGE_DAO;
            case DAO_IMPL:
                return BASE_PACKAGE_DAO_IMPL;
            case GRAPH:
                return BASE_PACKAGE_GRAPH;
            case DTO:
                return BASE_PACKAGE_DTO;
            case DTO_MAPPER:
                return BASE_PACKAGE_DTO_MAPPER;
            case SERVICE:
                return BASE_PACKAGE_SERVICE;
            case SERVICE_IMPL:
                return BASE_PACKAGE_SERVICE_IMPL;
            case SAVE_FORM:
            case UPDATE_FORM:
                return BASE_PACKAGE_FORM;
            case PAGE_FORM:
            case LIST_FORM:
                return BASE_PACKAGE_SEARCHER;
            case SAVE_MAPPER:
            case UPDATE_MAPPER:
                return BASE_PACKAGE_FORM_MAPPER;
            case CONTROLLER:
                return BASE_PACKAGE_CONTROLLER;
            case SQL:
                return BASE_SQL;
            default:
                throw new IllegalArgumentException("模板不存在");
        }

    }

    /**
     * 将包名替换为路径，然后根据模板获取到文件生成的目录。
     *
     * @param templateEnum
     *         模板
     *
     * @return 模板文件写入磁盘的路径以及包名
     *
     * @throws IllegalArgumentException
     */
    private static Pair <String, String> getPathAndPackage (TemplateEnum templateEnum) {

        String packageName = getPackageName(templateEnum);

        String packageToDir = packageName.replaceAll("\\.", "/") + "/";

        switch (templateEnum) {
            case DAO:
                return Pair.of(DAO_LOCATION + packageToDir, packageName);
            case DAO_IMPL:
                return Pair.of(DAO_IMPL_LOCATION + packageToDir, packageName);
            case GRAPH:
                return Pair.of(GRAPH_LOCATION + packageToDir, packageName);
            case DTO:
                return Pair.of(DTO_LOCATION + packageToDir, packageName);
            case DTO_MAPPER:
                return Pair.of(DTO_MAPPER_LOCATION + packageToDir, packageName);
            case SERVICE:
                return Pair.of(SERVICE_LOCATION + packageToDir, packageName);
            case SERVICE_IMPL:
                return Pair.of(SERVICE_IMPL_LOCATION + packageToDir, packageName);
            case SAVE_FORM:
            case UPDATE_FORM:
            case PAGE_FORM:
            case LIST_FORM:
                return Pair.of(FORM_LOCATION + packageToDir, packageName);
            case SAVE_MAPPER:
            case UPDATE_MAPPER:
                return Pair.of(FORM_MAPPER_LOCATION + packageToDir, packageName);
            case CONTROLLER:
                return Pair.of(CONTROLLER_LOCATION + packageToDir, packageName);
            case SQL:
                return Pair.of(SQL_LOCATION + packageToDir, packageName);
            default:
                throw new IllegalArgumentException("模板不存在");
        }

    }
}
